﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Crm.SdkTypeProxy;
using XrmLinq.Entities;

namespace XrmLinq.Examples
{
    class Program
    {
        private static CrmService _sdk;
        static void Main(string[] args)
        {
            // create a connection to CRM, use the on-premise url or IFD url, Create method will automatically create the appropriate connection for you
            _sdk = Connection.Create("http://server:5555/mscrmservices/2007/crmservice.asmx", "DemoOrg", "SomeDomain", "Administrator", "P@ssw0rd");
            if (_sdk == null)
            {
                throw new ArgumentNullException("_sdk", "A call to Connection.Create failed, please check your parameters");
            }

            CreateExample();

            UpdateExample();

            RetrieveExample();

            DeleteExample();
        }

        private static void RetrieveExample()
        {
            Account myAccount = null;
            try
            {
                myAccount = CrmDataAccess.Retrieve<Account>(_sdk, Account.Fields.SchemaName, Account.Fields.AccountId, Guid.Empty);

            }
            catch (CrmException ce) // CrmException will only catch SoapExceptions
            {
                Console.WriteLine("Error retrieving account\r\n{0}\r\n{1}", ce.Message, ce.InnerException.ToString());
            }

            if (myAccount != null)
            {
                Console.WriteLine("AccountId: {0}", myAccount.AccountId);
                Console.WriteLine("Name: {0}", myAccount.Name);
                Console.WriteLine("Category: {0}", // all picklist values are mapped to enums
                    myAccount.AccountCategoryCode.HasValue ? myAccount.AccountCategoryCode.Value.ToString() : "n/a"); 

                // lazy load 1:N links
                List<Invoice> invoices = myAccount.AccountInvoices;
                for (int i = 0; i < invoices.Count; i++)
                {
                    Invoice current = invoices[i];
                    Console.WriteLine("Invoice No.: {0}", current.InvoiceNumber);
                    Console.WriteLine("Amount: {0}", current.TotalAmount);
                    Console.WriteLine("Status: {0}", current.StateCode);
                }

                // lazy load N:1 link
                Account parent = myAccount.ParentAccount;
                if (parent != null)
                {
                    Console.WriteLine("Parent AccountId: {0}", parent.AccountId);
                    Console.WriteLine("Parent Account Name: {0}", parent.Name);
                }
            }
        }

        private static void CreateExample()
        {
            Account myAccount = new Account
            {
                AccountId = Guid.NewGuid(), // must be assigned, we don't automatically assign PKs
                Name = "My Shiny New Account",
                CreditLimit = 1000000m, // no need to use crm data types (eg: CrmMoney)
                DoNotBulkEMail = true, // another example of not using crm data types (CrmBoolean)
                AccountCategoryCode = Account.Enums.AccountCategoryCode.PreferredCustomer // all picklists are mapped to enums
            };

            try
            {
                CrmDataAccess.Create<Account>(_sdk, myAccount);
                Console.WriteLine("Successfully created {0}", myAccount.Name);
            }
            catch (CrmException ce) // CrmException will only catch SoapExceptions
            {
                Console.WriteLine("Error creating account\r\n{0}\r\n{1}", ce.Message, ce.InnerException.ToString());
            }
        }

        private static void UpdateExample()
        {
            // you can retrieve an existing account using CrmDataAccess.Retrieve or if you know the entityId simply assign it to the PK, for example:
            Account myAccount = new Account
            {
                AccountId = Guid.Empty,
                Name = "Updated Account Name"
            };

            try
            {
                CrmDataAccess.Update<Account>(_sdk, myAccount);
                Console.WriteLine("Successfully updated {0}", myAccount.AccountId);
            }
            catch (CrmException ce) // CrmException will only catch SoapExceptions
            {
                Console.WriteLine("Error updating account\r\n{0}\r\n{1}", ce.Message, ce.InnerException.ToString());
            }
        }

        private static void DeleteExample()
        {
            try
            {
                CrmDataAccess.Delete(_sdk, Guid.Empty, Account.Fields.SchemaName);
                Console.WriteLine("Successfully deleted {0}", Guid.Empty);
            }
            catch (CrmException ce) // CrmException will only catch SoapExceptions
            {
                Console.WriteLine("Error deleting account\r\n{0}\r\n{1}", ce.Message, ce.InnerException.ToString());
            }
        }
    }
}
